package com.Xingcang_Dianxue.WhutBank.Models;

import com.Xingcang_Dianxue.WhutBank.Views.ViewFactory;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;


public class Model {
    private static Model model;
    private final ViewFactory viewFactory;
    private final DatabaseDriver databaseDriver;


    // Client Data Section
    private final Client client;
    private final ObservableList<Transaction> allTransactions;
    private final DoubleProperty totalIncome;
    private final DoubleProperty totalExpenses;
    private boolean clientLoginSuccessFlag;

    public Model() {
        this.viewFactory = new ViewFactory();
        this.databaseDriver = new DatabaseDriver();
        // Client Data Section
        this.client = new Client("", "", null, null);
        this.clientLoginSuccessFlag = false;
        this.allTransactions = FXCollections.observableArrayList();

        this.totalIncome = new SimpleDoubleProperty(0);
        this.totalExpenses = new SimpleDoubleProperty(0);
    }

    public static Model getInstance() {
        if (model == null) {
            model = new Model();
        }
        return model;
    }


    public DoubleProperty totalIncomeProperty() {
        return totalIncome;
    }


    public DoubleProperty totalExpensesProperty() {
        return totalExpenses;
    }

    // Getter and Setter
    public ViewFactory getViewFactory() {
        return viewFactory;
    }

    public DatabaseDriver getDatabaseDriver() {
        return databaseDriver;
    }

    public boolean getClientLoginSuccessFlag() {
        return clientLoginSuccessFlag;
    }

    public void setClientLoginSuccessFlag(boolean clientLoginSuccessFlag) {
        this.clientLoginSuccessFlag = clientLoginSuccessFlag;
    }


    public Client getClient() {return client;}

    // Client Data Section
    public void evaluateClientCred(String phoneNumber, String password) {
        // 获取查询到的Client对象并把查询结果绑定到Client对象的属性值，并设置登录成功标志
        if (databaseDriver.getClientData(phoneNumber, password) != null) {
            try {
                Client searched_Client = databaseDriver.getClientData(phoneNumber, password);
                this.client.phoneNumberProperty().set(searched_Client.getPhoneNumber());
                this.client.userNameProperty().set(searched_Client.getUserName());
                this.client.dateCreatedProperty().set(searched_Client.getDateCreated());
                this.client.checkingAccountProperty().set(getCheckingAccount(phoneNumber));
                double totalIncome = 0;
                double totalExpenses = 0;
                for (Transaction transaction : databaseDriver.getTransactions(phoneNumber)) {
                    if (transaction.getType().equals("存款") || (transaction.getType().equals("转账") && transaction.getReceiver().equals(client.getPhoneNumber()))) {
                        totalIncome += transaction.getAmount();
                    }
                    if (transaction.getType().equals("取款") || (transaction.getType().equals("转账") && transaction.getSender().equals(client.getPhoneNumber()))) {
                        totalExpenses += transaction.getAmount();
                    }
                }
                this.totalIncome.set(totalIncome);
                this.totalExpenses.set(totalExpenses);
                this.clientLoginSuccessFlag = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void setAllTransactions() {
        this.allTransactions.addAll(databaseDriver.getTransactions(client.getPhoneNumber()));
    }

    public ObservableList<Transaction> getAllTransactions() {
        return allTransactions;
    }


    /*
     * Utility Methods Section
     * */
    public CheckingAccount getCheckingAccount(String Owner) {
        if (databaseDriver.getCheckingAccountData(Owner) != null) {
            try {
                return databaseDriver.getCheckingAccountData(Owner);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }


}
